/**
 * Created by henian.xu on 2020/4/5.
 *
 */

import jsSdk from 'jweixin';
import { GlobalVar, Device } from 'utils';
import Url from 'url';
import Qs from 'qs';
import Router from 'router';
import { Http } from '@/api';

const defaultConfig = {
  debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
  jsApiList: [
    'openEnterpriseChat',
    'openEnterpriseContact',
    'onMenuShareTimeline',
    'onMenuShareAppMessage',
    'onMenuShareQQ',
    'onMenuShareWeibo',
    'onMenuShareQZone',
    'startRecord',
    'stopRecord',
    'onVoiceRecordEnd',
    'playVoice',
    'pauseVoice',
    'stopVoice',
    'onVoicePlayEnd',
    'uploadVoice',
    'downloadVoice',
    'chooseImage',
    'previewImage',
    'uploadImage',
    'downloadImage',
    'translateVoice',
    'getNetworkType',
    'openLocation',
    'getLocation',
    'hideOptionMenu',
    'showOptionMenu',
    'hideMenuItems',
    'showMenuItems',
    'hideAllNonBaseMenuItem',
    'showAllNonBaseMenuItem',
    'closeWindow',
    'scanQRCode',
  ], // 必填，需要使用的JS接口列表，所有JS接口列表见附录2
};

let readyed = false;

async function initJweixinSdk() {
  const wxCfg = GlobalVar.wx || {};
  const { error_code, error_msg, data } = await Http.get(
    '/api/dwll_q2_active/jsTickets',
    { rdurl: window.location.href.split('#')[0] },
  );
  if (error_code) {
    if (Device.weixin) console.error(error_msg);
    return;
  }
  // console.log(data);
  jsSdk.config({
    ...defaultConfig,
    ...wxCfg,
    ...data,
  });
}

const shareFnMap = {
  timeline: 'onMenuShareTimeline', // 分享到朋友圈
  appMessage: 'onMenuShareAppMessage', // 分享给朋友
  qq: 'onMenuShareQQ', // 分享到QQ
  weibo: 'onMenuShareWeibo', // 分享到腾讯微博
  qzone: 'onMenuShareQZone', // 分享到QQ空间
};

export async function isReady() {
  return new Promise((resolve, reject) => {
    if (!Device.weixin && !GlobalVar.isDev) {
      return reject(new Error('当前非微信浏览器环境'));
    }
    if (readyed) return resolve(true);
    // config信息验证后会执行ready方法，
    // 所有接口调用都必须在config接口获得结果之后，
    // config是一个客户端的异步操作，所以如果需要在页面加载时就调用相关接口，则须把相关接口放在ready函数中调用来确保正确执行。
    // 对于用户触发时才调用的接口，则可以直接调用，不需要放在ready函数中。
    jsSdk.ready(() => {
      readyed = true;
      resolve(readyed);
    });
    return null;
  });
}

/**
 * 微信扫码
 * @param needResult
 * @param scanType
 * @returns {Promise<unknown>}
 */
export async function scanQRCode({ needResult, scanType } = {}) {
  await isReady();
  return new Promise((resolve, reject) => {
    jsSdk.scanQRCode({
      needResult: needResult || 1, // 默认为1，直接返回扫描结果，0则扫描结果由微信处理，
      scanType: scanType || ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码，默认二者都有
      success: (res) => resolve(res),
      error: (res) => reject(res),
    });
  });
}

export async function previewImage(current, urls) {
  return isReady().then(() => {
    jsSdk.previewImage({
      current, // 当前显示图片的http链接
      urls, // 需要预览的图片http链接列表
    });
  });
}

async function shareDataAdapter(data) {
  // title: '', // 分享标题
  // desc: '', // 分享描述
  // link: '', // 分享链接，该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
  // imgUrl: '', // 分享图标
  // type: '', // 分享类型,music、video或link，不填默认为link
  // dataUrl: '', // 如果type是music或video，则要提供数据链接，默认为空

  const keyMap = {
    imgUrl: 'imageUrl',
    desc: 'content',
    link: 'url',
  };
  const res = Object.entries(keyMap).reduce(
    (pre, [key, value]) => {
      pre[key] = data[value];
      return pre;
    },
    { ...data },
  );
  const { app, currentRoute } = Router;
  await app.$nextTick();
  if (!res.shareUrl) {
    const { fullPath } = currentRoute;
    // 获取当前路由url
    const uri = Url.parse(fullPath);
    const query = Qs.parse(uri.query);
    delete query.VNK;
    const search = Qs.stringify({
      ...query,
      fromShare: '',
    });
    uri.search = search ? `?${search}` : null;
    res.shareUrl = uri.format();
  }
  // 获取本地url
  const baseUrl = res.link || window.location.href.split('#')[0];
  const baseUri = Url.parse(baseUrl);
  const joinStr = `${baseUri.search ? '&' : '?'}gotoUrl=`;
  res.link = `${baseUrl}${joinStr}${encodeURIComponent(res.shareUrl)}`;
  return res;
}
export async function setShare(data) {
  await isReady();
  if (data) {
    data = await shareDataAdapter(data);
    // console.log(data);
    Object.entries(shareFnMap).forEach(([key, fn]) => {
      jsSdk[fn]({
        ...data,
        ...data[key],
        success() {
          if (data.success) data.success(key);
        },
        error(err) {
          console.log(err);
        },
      });
    });
  }
  const { wx } = window;
  if (wx && wx.miniProgram) {
    wx.miniProgram.getEnv((res) => {
      if (res.miniprogram) {
        wx.miniProgram.postMessage({ data });
      }
    });
  }
}

export async function hideAllNonBaseMenuItem() {
  await isReady();
  return new Promise((resolve, reject) => {
    if (Device.weixinMiniProgram) {
      resolve('miniProgram');
      return;
    }
    jsSdk.hideAllNonBaseMenuItem({
      success: (res) => {
        return resolve(res);
      },
      error: (res) => reject(res),
    });
  });
}
export async function showAllNonBaseMenuItem() {
  await isReady();
  return new Promise((resolve, reject) => {
    if (Device.weixinMiniProgram) {
      resolve('miniProgram');
      return;
    }
    jsSdk.showAllNonBaseMenuItem({
      success: (res) => {
        return resolve(res);
      },
      error: (res) => reject(res),
    });
  });
}

export async function getLocation(type = 'wgs84') {
  await isReady();
  return new Promise((resolve, reject) => {
    jsSdk.getLocation({
      type,
      success: (res) => {
        return resolve(res);
      },
      error: (res) => reject(res),
    });
  });
}

export async function openLocation({
  latitude,
  longitude,
  name,
  address,
  scale,
  infoUrl,
} = {}) {
  jsSdk.openLocation({
    latitude, // 纬度，浮点数，范围为90 ~ -90
    longitude, // 经度，浮点数，范围为180 ~ -180。
    name, // 位置名
    address, // 地址详情说明
    scale, // 地图缩放级别,整形值,范围从1~28。默认为最大
    infoUrl, // 在查看位置界面底部显示的超链接,可点击跳转
  });
}

async function closeWindow() {
  jsSdk.closeWindow();
}

export default (Vue) => {
  /*const wxCfg = GlobalVar.wx || {};
  jsSdk.config({
    ...defaultConfig,
    appId: wxCfg.appid,
    nonceStr: wxCfg.nonce,
    signature: wxCfg.signature,
    timestamp: wxCfg.timestamp,
  });*/
  if (jsSdk) {
    initJweixinSdk();
  } else {
    console.error('微信 jweixin.js 文件未加载!');
  }

  Vue.prototype.$wx = jsSdk;
  Vue.prototype.$wxSDK = {
    isReady,
    scanQRCode,
    previewImage,
    setShare,
    hideAllNonBaseMenuItem,
    showAllNonBaseMenuItem,
    closeWindow,
    getLocation,
    openLocation,
  };
};
